package design.patterns.creational.singleton.lazy.v3;

/**
 * @author gjx
 * @version v1.0
 * @Description
 * @date 2019/4/1 10:32
 */

import design.patterns.creational.singleton.MyThread;

/**
 * 懒汉式 线程安全单例示例
 */
public class LazySingleton {
//    private static LazySingleton lazySingleton = null;
    private static volatile LazySingleton lazySingleton = null;

    private LazySingleton(){

    }

    /**
     *
     * 双重检查锁  会存在bug ，bug 原因在于 创建对象的2，3步骤 ，假如线程A 还未初始化对象。 线程B通过if 不为空判断直接返回一个未
     * 初始化的对象。 解决方案 禁止 指令重排序。加入volatile 关键字
     */
    public static LazySingleton getInstance(){
        if(lazySingleton == null){
            synchronized (LazySingleton.class) {
                if(lazySingleton == null) {
                    lazySingleton = new LazySingleton();
                    // 1 分配对象的内存空间
                    // 2 设置lazySingleton 指向内存空间
                    // 3 初始化对象
                    // 2,3可以交换
                }
            }
        }
        return lazySingleton;
    }
}


class Test {
    public static void main(String[] args) {
        //单线程测试
       /* LazySingleton instance = LazySingleton.getInstance();
        System.out.println(instance);

        LazySingleton instance2 = LazySingleton.getInstance();
        System.out.println(instance2);*/
        //多线程测试
        int count = 800;
        for (int i = 0; i < count; i++) {
            MyThread t1 = new MyThread();
            t1.start();

        }
        System.out.println("main....");

    }
}
